package com.origin.niuke.dfs;

/**
 * NC138 矩阵最长递增路径
 * 算法：记忆化搜索
 * dp[i][j]: 从 (i, j) 位置出发的最长递增路径
 * dp[i][j] 为 Math.max(dp[i][j - 1], dp[i][j + 1], dp[i - 1][j], dp[i + 1][j]) + 1
 * 使用 dp 数组可以减少递归次数, 当 dp[i][j] 不为 0 时, 表示 (i, j) 的最长递增路径已经算过了, 直接返回即可
 *
 * @author yezh
 * @version 1.0
 * @date 2022/10/30 20:45
 */
public class NC138 {

    int n, m;
    int[][] dirs = new int[][]{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

    public int solve(int[][] matrix) {
        // write code here
        int ans = 0;
        n = matrix.length; m = matrix[0].length;
        int[][] dp = new int[n][m];
        for (int i = 0; i < n; i++) for (int j = 0; j < m; j++)
            ans = Math.max(ans, dfs(i, j, matrix, dp));
        return ans;
    }

    int dfs(int i, int j, int[][] matrix, int[][] dp) {
        if (dp[i][j] != 0) return dp[i][j];
        ++dp[i][j];
        for (int[] dir : dirs) {
            int nextI = i + dir[0], nextJ = j + dir[1];
            if (nextI >= 0 && nextI < n && nextJ >= 0 && nextJ < m && matrix[i][j] < matrix[nextI][nextJ])
                dp[i][j] = Math.max(dp[i][j], dfs(nextI, nextJ, matrix, dp) + 1);
        }
        return dp[i][j];
    }

}
